package com.xiaoxin.experience.util;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.Assert;

import java.security.MessageDigest;

/**
 * MD5加密算法
 *
 * @author user
 * @version [版本号, 2014-5-28]
 * @see [相关类/方法]
 * @since [产品/模块版本]
 */
public final class MD5
{
    private static final Logger LOG = LoggerFactory.getLogger(MD5.class);

    private final static char[] strDigits =
            {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};

    private MD5()
    {
    }

    public static String md5(String source)
    {
        return byteToString(md5Bytes(source));
    }

    public static String md5(byte[] bytes)
    {
        return byteToString(md5Bytes(bytes));
    }

    public static byte[] md5Bytes(String source)
    {
        Assert.notNull(source, "md5 source input is null.");
        return md5Bytes(source.getBytes());
    }

    public static byte[] md5Bytes(byte[] bytes)
    {
        try
        {
            MessageDigest md = MessageDigest.getInstance("MD5");
            return md.digest(bytes);
        }
        catch (Exception e)
        {
            LOG.error("md5 fail.", e);
            return null;
        }
    }

    /**
     * 转换字节数组为16进制字串
     *
     * @param bytes bytes
     * @return 16进制字串
     */
    private static String byteToString(byte[] bytes)
    {
        if (null == bytes)
        {
            return "";
        }

        StringBuilder sBuffer = new StringBuilder();
        for (byte bByte : bytes)
        {
            int iRet = bByte;
            if (iRet < 0)
            {
                iRet += 256;
            }
            sBuffer.append(strDigits[iRet / 16]);
            sBuffer.append(strDigits[iRet % 16]);
        }
        return sBuffer.toString();
    }

}
